#pragma once

#include "Common.h"

#include <cstddef>
#include <map>
#include <mutex>

namespace mp {

class PageCache {
  private:
    struct Span {
        void *pageAddr;   // 页起始地址
        size_t numPages;  // 页数
        Span *next;
    };

  public:
    static const size_t PAGE_SIZE = 4096;  // 4K 页大小

  public:
    static PageCache &getInstance() {
        static PageCache instance;
        return instance;
    }

    void *allocateSpan(size_t numPages);              // 分配指定页数的span
    void deallocateSpan(void *ptr, size_t numPages);  // 释放span

  private:
    PageCache() = default;
    void *systemAlloc(size_t numPages);  // 向系统申请内存

  private:
    std::map<size_t, Span *> freeSpans_;  // 按页数管理空闲 span，不同页数对应不同 span 链表
    std::map<void *, Span *> spanMap_;    // 页号到 span 的映射，用于回收
    std::mutex mtx_;
};

}  // namespace mp